package changedb;


import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.UIManager;

import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeSelectionModel;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;

import java.net.URL;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.JTextArea;

/**
 *
 * @author Ben Goodwin
 * @version 2.0 16/09/2011
 */
public class Help extends JPanel implements TreeSelectionListener {

    private JTree tree;
    private URL helpURL;
    private JTextArea textPane;

    public Help() {
        super(new GridLayout(1,0));
        DefaultMutableTreeNode root = new DefaultMutableTreeNode("Help");
        createNodes(root);
        tree = new JTree(root);
        tree.setRootVisible(false);
        tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
        tree.addTreeSelectionListener(this);
        JScrollPane treeView = new JScrollPane(tree);
        textPane = new JTextArea();
        textPane.setEditable(false);
        textPane.setFont(new java.awt.Font("Verdana", 0, 12));
        textPane.setLineWrap(true);
        textPane.setText("Please select a help option from the left.");
        textPane.setWrapStyleWord(true);
        JScrollPane textView = new JScrollPane(textPane);

        //Add the scroll panes to a split pane.
        JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
        splitPane.setLeftComponent(treeView);
        splitPane.setRightComponent(textView);

        Dimension minimumSize = new Dimension(600, 400);
        textView.setMinimumSize(minimumSize);
        treeView.setMinimumSize(minimumSize);
        splitPane.setDividerLocation(150);
        splitPane.setPreferredSize(new Dimension(600, 400));
        add(splitPane);
        createGUI();
    }

    /** Required by TreeSelectionListener interface. */
    public void valueChanged(TreeSelectionEvent e) {
        DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();

        if (node == null) {
            return;
        }

        Object nodeInfo = node.getUserObject();
        if (node.isLeaf()) {
            HelpInfo help = (HelpInfo) nodeInfo;
            textPane.setText(help.getText());
        } else {
            textPane.setText("Please select a help option from the left.");
        }
    }

    private class HelpInfo {

        public String helpName;
        public String helpText;

        public HelpInfo(String name, String text) {
            helpName = name;
            helpText = text;
            if (helpText == null) {
                helpText = "Error";
            }
        }

        @Override
        public String toString() {
            return helpName;
        }

        public String getText() {
            return helpText;
        }
    }

    private void createNodes(DefaultMutableTreeNode root) {
        DefaultMutableTreeNode category = null;
        DefaultMutableTreeNode help = null;

        category = new DefaultMutableTreeNode("File Options");
        root.add(category);
        help = new DefaultMutableTreeNode(new HelpInfo("Opening a File",
                "The Open function (Ctrl + O) will open up a file chooser where you can then select the database in a .xml file. This file must be created by this program or it will not load correctly."));
        category.add(help);
        help = new DefaultMutableTreeNode(new HelpInfo("Saving a File",
                "There are three ways to save an open file, the first is the simple 'Save' option (Ctrl + S), saving the current file to disk. The second is the 'Save As' option (Ctrl + Shift + S), re-saving your file under a different file name. The third option is an 'Encrypt' save, which saves the file but encrypts the data using a simple encryption key. If you have no current open file, the Save function will call Save As."));
        category.add(help);
        help = new DefaultMutableTreeNode(new HelpInfo("Closing a File",
                "The Close function (Ctrl + W) will close the current file, allowing you to work in a new unsaved project."));
        category.add(help);
        category = new DefaultMutableTreeNode("Member Options");
        root.add(category);

        help = new DefaultMutableTreeNode(new HelpInfo("Adding Members",
                "To add a new member, go to the green + button on the toolbar, or Edit -> Add. This brings up a window with the option to add new details. Warning - There is currently no validation on the type of data you enter. First and last name are the only compulsory fields.\n\nTo select a picture, click on the default picture and select a .jpg image. This picture should ideally be of maximum size 200,150.\n\nPlease note: No changes are made until the Save button is pressed, and only then will the picture be saved to a local directory for use with the application."));
        category.add(help);
        help = new DefaultMutableTreeNode(new HelpInfo("Editing Members",
                "To edit a member, make sure a member is selected in the list and go to the blue + icon on the toolbar, or Edit -> Edit. This brings up a window to edit the members details. Warning - There is currently no validation on the type of data you enter. First and last name are the only compulsory fields.\n\nTo select (or change) a picture,click on the default picture and select a .jpg image. This picture should ideally be of maximum size 200,150.\n\nPlease note: No changes are made until the Save button is pressed, and only then will the picture be saved to a local directory for use with the application."));
        category.add(help);
        help = new DefaultMutableTreeNode(new HelpInfo("Deleting Members",
                "This can be done by clicking the red X button on the toolbar, or by going File -> Delete, but only if a member is selected from the list. This action cannot be undone."));
        category.add(help);

        category = new DefaultMutableTreeNode("Functions");
        root.add(category);
        help = new DefaultMutableTreeNode(new HelpInfo("Filter Function",
                "The 4 filter options above the list; All, Leader, Change and Ignite; only show the respective members of each type."));
        category.add(help);
        help = new DefaultMutableTreeNode(new HelpInfo("List Function",
                "The list function on the left lists all the members from the currently open file. Single left-clicking a member from the list shows that person in the Details panel on the right."));
        category.add(help);
        help = new DefaultMutableTreeNode(new HelpInfo("Mail-to Function",
                "The mail-to function currently only supports GMail accounts, but will email from inside of the application using the details provided. Use the check boxes to select the type of members to send the email out to, or if you want to further edit the selection you can copy and paste the emails from the box for use in another email client. The emails will be sent out with the respective person's first and last (if selected) names inserted."));
        category.add(help);

        category = new DefaultMutableTreeNode("Future Ideas");
        root.add(category);
        help = new DefaultMutableTreeNode(new HelpInfo("Suggestions",
                "If you have any suggestions for ChangeDB, or any queries about certain features not covered in this help file, please do not hesitate to contact me.\nMy email is bg93@kent.ac.uk\nIf contacting with a suggestion for the program, please put \"ChangeDB - Suggestions\" as the subject line and if contacting with a query about the program, please put \"ChangeDB - Query\" as the subject line."));
        category.add(help);
        help = new DefaultMutableTreeNode(new HelpInfo("Future Changes",
                "I have no current updates planned for this project."));
        category.add(help);
        help = new DefaultMutableTreeNode(new HelpInfo("Known Bugs",
                "Here will be kept a list of currently known bugs (or glitches):\n\nNone!\nThere are currently no known bugs. If you have found one, please see the Reporting Bugs page."));
        category.add(help);
        help = new DefaultMutableTreeNode(new HelpInfo("Bug Reporting",
                "A 'Bug' or 'Glitch' is when a function does not work as it should, or produces an expected result or error. If you recieve such a problem, first of all check Known Bugs to see if this problem has been reported before, and if not please contact me. Bugs do not necessarily include pop-up's warning of an Error unless they are consistently occuring.\n\nContacting me can be done by emailing me at bg93@kent.ac.uk with \"ChangeDB - New Bug\" as the subject line, detailing what you were attempting to achieve, what you had previously clicked, your current version (found in the About section, or shown as you load the program) and (if possible) the error printed."));
        category.add(help);
    }

    /**
     * Create the GUI and show it.  For thread safety,
     * this method should be invoked from the
     * event dispatch thread.
     */
    private static void createAndShowGUI() {
        try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); }
        catch (Exception e) {}

        //Create and set up the window.
        JFrame frame = new JFrame("Help");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        //Add content to the window.
        frame.add(new Help());

        //Display the window.
        frame.pack();
        frame.setVisible(true);
        java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
        frame.setBounds((screenSize.width-616)/2, (screenSize.height-438)/2, 616, 438);
    }


    private void createGUI() {
        JFrame frame = new JFrame("Help");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        //Add content to the window.
        frame.add(this);

        //Display the window.
        frame.pack();
        frame.setVisible(true);
        java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
        frame.setBounds((screenSize.width-616)/2, (screenSize.height-438)/2, 616, 438);
    }

    public static void main(String[] args) {
        //Schedule a job for the event dispatch thread:
        //creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                createAndShowGUI();
            }
        });
    }
}
